package com.lesliefang;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class CommandExecutor {

    /**
     * 执行系统命令（简单版本）
     *
     * @param command 命令字符串
     * @return 命令执行结果
     */
    public static String executeCommand(String command) throws IOException, InterruptedException {
        ProcessBuilder processBuilder = new ProcessBuilder();

        // 根据操作系统设置命令
        if (System.getProperty("os.name").toLowerCase().contains("windows")) {
            processBuilder.command("cmd.exe", "/c", command);
        } else {
            processBuilder.command("sh", "-c", command);
        }

        // 启动进程
        Process process = processBuilder.start();

        // 读取输出
        StringBuilder output = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));

        String line;
        while ((line = reader.readLine()) != null) {
            output.append(line).append("\n");
        }

        // 等待进程结束
        int exitCode = process.waitFor();
        if (exitCode != 0) {
            // 读取错误输出
            BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            StringBuilder errorOutput = new StringBuilder();
            String errorLine;
            while ((errorLine = errorReader.readLine()) != null) {
                errorOutput.append(errorLine).append("\n");
            }
            throw new RuntimeException("命令执行失败，退出码: " + exitCode + "\n错误信息: " + errorOutput.toString());
        }

        return output.toString();
    }

    /**
     * 执行系统命令（高级版本，支持超时和详细配置）
     *
     * @param command     命令列表
     * @param timeout     超时时间（毫秒）
     * @param directory   工作目录
     * @param environment 环境变量
     * @return 执行结果对象
     */
    public static CommandResult executeCommand(List<String> command, long timeout,
                                               String directory, String[] environment) {
        try {
            ProcessBuilder processBuilder = new ProcessBuilder(command);

            // 设置工作目录
            if (directory != null && !directory.isEmpty()) {
                processBuilder.directory(new java.io.File(directory));
            }

            // 设置环境变量
            if (environment != null) {
                for (String env : environment) {
                    String[] parts = env.split("=", 2);
                    if (parts.length == 2) {
                        processBuilder.environment().put(parts[0], parts[1]);
                    }
                }
            }

            // 启动进程
            Process process = processBuilder.start();

            // 设置超时
            boolean finished = process.waitFor(timeout, TimeUnit.MILLISECONDS);
            if (!finished) {
                process.destroyForcibly();
                return new CommandResult(false, "", "命令执行超时", -1);
            }

            // 读取标准输出
            String output = readStream(process.getInputStream());

            // 读取错误输出
            String errorOutput = readStream(process.getErrorStream());

            int exitCode = process.exitValue();

            return new CommandResult(exitCode == 0, output, errorOutput, exitCode);

        } catch (Exception e) {
            return new CommandResult(false, "", e.getMessage(), -1);
        }
    }

    /**
     * 读取输入流内容
     */
    private static String readStream(java.io.InputStream inputStream) throws IOException {
        StringBuilder result = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line).append("\n");
            }
        }
        return result.toString();
    }

    /**
     * 命令执行结果类
     */
    public static class CommandResult {
        private final boolean success;
        private final String output;
        private final String errorOutput;
        private final int exitCode;

        public CommandResult(boolean success, String output, String errorOutput, int exitCode) {
            this.success = success;
            this.output = output;
            this.errorOutput = errorOutput;
            this.exitCode = exitCode;
        }

        public boolean isSuccess() {
            return success;
        }

        public String getOutput() {
            return output;
        }

        public String getErrorOutput() {
            return errorOutput;
        }

        public int getExitCode() {
            return exitCode;
        }

        @Override
        public String toString() {
            return "CommandResult{" +
                    "success=" + success +
                    ", exitCode=" + exitCode +
                    ", output='" + output + '\'' +
                    ", errorOutput='" + errorOutput + '\'' +
                    '}';
        }
    }

    // 使用示例
    public static void main(String[] args) {
        try {
            // 简单使用示例
            System.out.println("=== 简单命令执行 ===");
            String result1 = executeCommand("echo Hello World");
            System.out.println(result1);

            // 高级使用示例
            System.out.println("=== 高级命令执行 ===");
            List<String> command = List.of("java", "-version");
            CommandResult result2 = executeCommand(command, 5000, null, null);
            System.out.println(result2);

            // 列出目录内容
            System.out.println("=== 列出目录内容 ===");
            String listCommand = System.getProperty("os.name").toLowerCase().contains("windows")
                    ? "dir" : "ls -la";
            String result3 = executeCommand(listCommand);
            System.out.println(result3);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}